
package com.hlkj.pay.app.merchant.ext.impl.fuyou;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.common.IUploadService;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.access.*;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouConfig;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.handler.FuYouMerchantAccessConfigHandler;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.handler.FuYouMerchantAccessInfoHandler;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.utils.FuYouCallBackParamsParseUtil;
import com.hlkj.pay.dto.merchant.AccessChannelParamsDto;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.dto.merchant.MerchantWechatConfigDto;
import com.hlkj.pay.dto.pay.PayCommonAppDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.vo.order.resp.MerchantProductQueryResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 富友进件操作
 * 
 * @author HlpayTeam
 * @date 2024/09/26 10:25
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_FU_YOU)
public class FuYouMerchantAccessExtPt implements ChannelMerchantAccessExtPt {

    private final FuYouMerchantAccessInfoHandler fuYouMerchantAccessInfoHandler;

    private final FuYouMerchantAccessConfigHandler fuYouMerchantAccessConfigHandler;

    private final IUploadService uploadService;

    @Override
    public void channelConfigCheck(ChannelMerchantAccessCommonContext channelMerchantAccessCommonContext) {
        CommonResult<FuYouConfig> fuYouConfigCommonResult = fuYouMerchantAccessConfigHandler.channelConfigSubmit(channelMerchantAccessCommonContext.getProviderChannelConfig());
        if (!fuYouConfigCommonResult.isSuccess()) {
            channelMerchantAccessCommonContext.setRemark(fuYouConfigCommonResult.getMsg());
            channelMerchantAccessCommonContext.setProcessStatus(false);
        }
    }

    @Override
    public void merchantAccess(ChannelMerchantAccessContext channelMerchantAccessContext) {
        log.info("富友渠道提交进件 请求参数:{}", JsonUtils.toJsonString(channelMerchantAccessContext));

        fuYouMerchantAccessInfoHandler.merchantAccess(channelMerchantAccessContext);
        if (!channelMerchantAccessContext.isProcessStatus()) {
            if ("商户名重复".equals(channelMerchantAccessContext.getRemark())) {
                Integer nameCount = channelMerchantAccessContext.getNameCount();
                if (nameCount == null) {
                    nameCount = 0;
                }
                channelMerchantAccessContext.setNameCount(nameCount + 1);
                channelMerchantAccessContext.setProcessStatus(true);
                channelMerchantAccessContext.setRemark(null);
                merchantAccess(channelMerchantAccessContext);
            }
        }
    }

    @Override
    public String requestUrl(MerchantAccessDto merchantAccessInfoDO) {
        return "registration/merchant";
    }

    @Override
    public String channelParams(AccessChannelParamsDto accessChannelParamsDto) {
        FuYouAppChannelParams params = new FuYouAppChannelParams();
        params.setFuYouId(accessChannelParamsDto.getSubMchId());
        params.setTermId(accessChannelParamsDto.getTeamId());
        return JsonUtils.toJsonStringNotNull(params);
    }

    @Override
    public void merchantAccessQuery(ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessQueryContext.getMerchantAccessInfo();
        if (!StringUtils.hasText(merchantAccessInfoDO.getApplyNo()) && !StringUtils.hasText(merchantAccessInfoDO.getSubMchId())) {
            channelMerchantAccessQueryContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessQueryContext.setRemark("申请单号和商户号不能都为空");
            return;
        }
        fuYouMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessQueryContext);
    }

    @Override
    public void merchantSign(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {
        // 富友没有签约流程
        // channelMerchantAccessSignContext.setProcessStatus(CommonEnum.YES_NO_TYPE.YES);
        // 富友没有签约 直接进入待配置
        channelMerchantAccessSignContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
    }

    @Override
    public void merchantSignQuery(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {

    }

    @Override
    public void merchantBusinessOpen(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        MerchantEnum.CHANNEL_CONFIG_STATUS accessStatus = MerchantEnum.CHANNEL_CONFIG_STATUS.from(merchantAccessInfo.getAuditStatus());
        switch (accessStatus) {
            case SUBMIT:
                // 富友的业务开通就是电子协议生成 和签署电子协议
                fuYouMerchantAccessInfoHandler.processElecContract(channelMerchantBusinessContext);
                break;
            case SIGN:
                // 文件上传
                fuYouMerchantAccessInfoHandler.fileProcess(channelMerchantBusinessContext);
                break;
            case AUDIT:
                // 审核
                fuYouMerchantAccessInfoHandler.auditProcess(channelMerchantBusinessContext);
                break;
            case AUDITING:
                // 审核中
                ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext = new ChannelMerchantAccessQueryContext();
                channelMerchantAccessQueryContext.setMerchantAccessInfo(channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo());
                channelMerchantAccessQueryContext.setProviderChannelConfig(channelMerchantBusinessContext.getProviderChannelConfig());
                fuYouMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessQueryContext);
                if (channelMerchantBusinessContext.isProcessStatus()) {
                    channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.WECHAT_CONFIG);
                    channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_SUCCESS);
                }else {
                    channelMerchantBusinessContext.setLastAccessStatus(MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE);
                }
            default:
                channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_SUCCESS);
        }

    }

    @Override
    public void wechatConfigInit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        List<PayCommonAppDto> payCommonAppList = channelMerchantBusinessContext.getPayCommonAppList();
        List<PayCommonAppDto> wechatCommonApp = null;
        if (!CollectionUtils.isEmpty(payCommonAppList)) {
            wechatCommonApp = payCommonAppList.stream().filter(payCommonAppDto -> PayEnums.PAY_TYPE.WECHAT.getCode().equals(payCommonAppDto.getPayWayDO().getType()))
                    .collect(Collectors.toList());
        }
        MerchantWechatConfigDto merchantWechatConfigDto = channelMerchantBusinessContext.getMerchantWechatConfigDto();
        // 没有微信执行 配置完成
        if (CollectionUtils.isEmpty(wechatCommonApp) && merchantWechatConfigDto == null) {
            channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.WECHAT_AUTH);
            return;
        }
        // 文件上传完成就是微信参数自动配置
        fuYouMerchantAccessConfigHandler.processWxConfigSet(channelMerchantBusinessContext);
    }

    @Override
    public void wechatConfigAdd(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 文件上传完成就是微信参数自动配置
        fuYouMerchantAccessConfigHandler.processWxConfigSetAdd(channelMerchantBusinessContext);
    }

    @Override
    public void wechatConfigQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
        fuYouMerchantAccessConfigHandler.processWxConfigQuery(channelMerchantAccessAuthQueryContext);

    }

    @Override
    public void wechatAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 微信参数配置
        // 富友 为自动认证无需处理
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTH);
    }

    @Override
    public boolean authConfigQueryType() {
        return false;
    }

    @Override
    public void wechatAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
        fuYouMerchantAccessConfigHandler.processWxAuthQuery(channelMerchantAccessAuthQueryContext);
        processAuthQuery(channelMerchantAccessAuthQueryContext, 1);
        if (channelMerchantAccessAuthQueryContext.isProcessStatus()) {
            channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTH);
        }
    }

    @Override
    public void alipayAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        List<PayCommonAppDto> payCommonAppList = channelMerchantBusinessContext.getPayCommonAppList();
        List<PayCommonAppDto> wechatCommonApp = payCommonAppList.stream()
                .filter(payCommonAppDto -> PayEnums.PAY_TYPE.ALIPAY.getCode().equals(payCommonAppDto.getPayWayDO().getType())).collect(Collectors.toList());
        // 没有微信执行 配置完成
        if (CollectionUtils.isEmpty(wechatCommonApp)) {
            // merchantAccessInfo.setAuditStatus(FuYouEnum.ACCESS_STATUS.FINISH.getCode());
            channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
            return;
        }
        // 支付宝参数配置
        // 富友 为自动认证无需处理
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTHING);
    }

    @Override
    public void alipayAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
        fuYouMerchantAccessConfigHandler.processAliAuthQuery(channelMerchantAccessAuthQueryContext);
        processAuthQuery(channelMerchantAccessAuthQueryContext, 2);
        if (channelMerchantAccessAuthQueryContext.isProcessStatus()) {
            channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
        }
    }

    void processAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext, Integer type) {
        List<MerchantAccessAuthDO> merchantAccessAuthList = channelMerchantAccessAuthQueryContext.getMerchantAccessAuthList();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessAuthQueryContext.getMerchantAccessInfo();
        Map<String, MerchantAccessAuthDO> merchantAccessAuthDOMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(channelMerchantAccessAuthQueryContext.getMerchantAccessAuthDbList())) {
            merchantAccessAuthDOMap = channelMerchantAccessAuthQueryContext.getMerchantAccessAuthDbList().stream()
                    .collect(Collectors.toMap(merchantAccessAuthDO -> merchantAccessAuthDO.getSubMchId(), Function.identity(), (t1, t2) -> t1));
        }
        if (!CollectionUtils.isEmpty(merchantAccessAuthList)) {
            Map<String, MerchantAccessAuthDO> finalMerchantAccessAuthDOMap = merchantAccessAuthDOMap;
            merchantAccessAuthList.stream().forEach(merchantAccessAuthDO -> {
                merchantAccessAuthDO.setType(type);
                merchantAccessAuthDO.setSn(merchantAccessInfo.getSn());
                merchantAccessAuthDO.setAccessId(merchantAccessInfo.getId());
                MerchantAccessAuthDO accessAuthDO = finalMerchantAccessAuthDOMap.get(merchantAccessAuthDO.getSubMchId());
                if ((accessAuthDO == null || !StringUtils.hasText(accessAuthDO.getAuthUrl())) && merchantAccessAuthDO.getQrCodeArray() != null
                        && merchantAccessAuthDO.getQrCodeArray().length > 0) {
                    CommonResult<String> commonResult = uploadService.upload(merchantAccessAuthDO.getQrCodeArray(), CommonEnum.OssEnum.IMAGE);
                    if (commonResult.isSuccess()) {
                        merchantAccessAuthDO.setAuthUrl(commonResult.getData());
                    }
                    else {
                        log.error("富有授权查询图片上传失败:{}", commonResult.getMsg());
                    }
                }
            });
        }

    }

    @Override
    public MerchantAccessCallBackDto accessCallBackParamsParse(HttpServletRequest callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;

    }

    @Override
    public CommonResult<String> accessCallbackParse(String callBackBody, List<ProviderChannelConfigDO> channelConfigDOList) {
        return null;
    }

    @Override
    public MerchantBusinessCallBackDto businessCallBackParamsParse(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        return FuYouCallBackParamsParseUtil.businessCallBackParamsParse(callBackBody);
    }

    @Override
    public boolean verify(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        FuYouConfig fuYouConfig = JsonUtils.parseObject(channelConfig, FuYouConfig.class);
        return FuYouCallBackParamsParseUtil.verify(fuYouConfig, callBackBody);
    }

    @Override
    public String callBackResponse(CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "1";
        }
        else {
            return "0";
        }
    }

    @Override
    public void termAdd(ChannelMerchantTermContext channelMerchantTermContext) {
        // 先查询
        fuYouMerchantAccessConfigHandler.termQuery(channelMerchantTermContext);
        if (channelMerchantTermContext.isProcessStatus() && StringUtils.hasText(channelMerchantTermContext.getTermId())) {
            return;
        }
        fuYouMerchantAccessConfigHandler.termAdd(channelMerchantTermContext);
    }

    @Override
    public void reloadMerchantAuth(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public void channelSplit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public void productUpdate(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public Integer queryMerAuthStatus(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        return null;
    }

    @Override
    public MerchantProductQueryResp productQuery(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        return null;
    }

    @Override
    public MerchantChannelSplitCallBackDto easySplitCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;
    }

}
